package cc.ucanuup.service.base.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import cc.ucanuup.common.AppConsts;
import cc.ucanuup.common.support.easyui.EasyuiUtil;
import cc.ucanuup.common.support.easyui.inter.EasyuiQuery;
import cc.ucanuup.common.support.easyui.model.SearchComgrid;
import cc.ucanuup.common.support.easyui.view.EasyuiPage;
import cc.ucanuup.service.base.dao.MasterCodeJPA;
import cc.ucanuup.service.base.dto.MasterCodeDto;
import cc.ucanuup.service.base.entity.MasterCode;
import cc.ucanuup.service.base.enums.MasterCodeType;
import cc.ucanuup.service.base.inter.MasterCodeService;
import cc.ucanuup.utils.StringUtil;

/**
 * 文件名： com.bozhon.service.base.impl.MasterCodeServiceImpl.java
 * 作者： WenBin
 * 日期： 2017年11月9日
 * 功能说明： 字典服务类
 * =========================================================
 * 修改记录：
 * 修改作者 日期 修改内容
 * =========================================================
 * Copyright (c) 2010-2011 .All rights reserved.
 */
@Service
public class MasterCodeServiceImpl implements MasterCodeService {

	@Autowired
	private MasterCodeJPA					masterCodeJPA;
	@Autowired
	private MasterCodeService				masterCodeService;
	/*	@Autowired
	private RedisCacheService<MasterCode>	redisCacheService;*/

	/**
	 * @Description: 保存或者更新改对象信息
	 * @author WenBin
	 * @param entity
	 * @return
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public MasterCode save(MasterCode entity) {

		return masterCodeJPA.save(entity);
	}

	/**
	 * @Description: 通过主键查询对象信息
	 * @author WenBin
	 * @param id
	 * @return
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public MasterCode findOne(String id) {

		return masterCodeJPA.findOne(id);
	}

	/**
	 * @Description: 通过编码查询对象信息
	 * @author WenBin
	 * @param code
	 *            数据字典编码
	 * @return
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public MasterCode findOneByCode(Integer code) {

		return masterCodeJPA.findOneByCode(code);
	}

	/**
	 * @Description: 分页-查询最高级别菜单
	 * @author WenBin
	 * @param bzPage
	 * @return
	 * @throws Exception
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	//@BzData(permission={"permission"})
	@Override
	public Page<MasterCode> queryTopMasterCodes(EasyuiQuery bzPage) throws Exception {

		final Map<String, Object> map = EasyuiUtil.castQueryParam(bzPage);
		String[] sorts = bzPage.getSortArr();
		String[] oders = bzPage.getOrders();
		List<Order> orders = new ArrayList<Order>();
		Sort sort = null;
		if (sorts != null && sorts.length > 0) {
			Order od = null;
			for (int i = 0; i < sorts.length; i++) {
				if ("asc".equals(oders[i])) {
					od = new Order(Direction.ASC, sorts[i]);
				} else {
					od = new Order(Direction.DESC, sorts[i]);
				}
				orders.add(od);
			}
			sort = new Sort(orders);
		}
		PageRequest pageable = new PageRequest(bzPage.getPageNo(), bzPage.getPageSize(), sort);
		Specification<MasterCode> specification = new Specification<MasterCode>() {

			@Override
			public Predicate toPredicate(Root<MasterCode> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

				List<Predicate> list = new ArrayList<Predicate>();
				Predicate deleted = criteriaBuilder.equal(root.get("deleted"), AppConsts.DELETED_EXIST);
				list.add(deleted);

				Predicate level = criteriaBuilder.equal(root.get("dicLevel"), 0);
				list.add(level);

				if (map.get("dicDesc") != null) {
					Predicate dicDesc = criteriaBuilder.like(root.get("dicDesc").as(String.class),
							"%" + (String) map.get("dicDesc") + "%");
					list.add(dicDesc);
				}
				if (map.get("dicCode") != null) {
					Predicate dicCode = criteriaBuilder.equal(root.get("dicCode"), map.get("dicCode"));
					list.add(dicCode);
				}
				Predicate[] p = new Predicate[list.size()];
				return criteriaBuilder.and(list.toArray(p));
			}
		};
		Page<MasterCode> sourceCodes = masterCodeJPA.findAll(specification, pageable);
		return sourceCodes;
	}

	/**
	 * @Description: 分页- 查询子 数据字典信息
	 * @author WenBin
	 * @param bzPage
	 * @return
	 * @throws Exception
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	//@BzData(permission={"permission"})
	@Override
	public Page<MasterCode> querySunMasterCodes(EasyuiQuery bzPage) throws Exception {

		final Map<String, Object> map = EasyuiUtil.castQueryParam(bzPage);
		PageRequest pageable = new PageRequest(bzPage.getPageNo(), bzPage.getPageSize(), EasyuiUtil.getJpaSort(bzPage));
		Specification<MasterCode> specification = new Specification<MasterCode>() {

			@Override
			public Predicate toPredicate(Root<MasterCode> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

				List<Predicate> list = new ArrayList<Predicate>();
				Predicate deleted = criteriaBuilder.equal(root.get("deleted"), AppConsts.DELETED_EXIST);
				list.add(deleted);

				Predicate level = criteriaBuilder.equal(root.get("dicLevel"), 1);
				list.add(level);
				if (map.get("fatherId") != null) {
					Predicate fathreId = criteriaBuilder.equal(root.get("fatherId"), map.get("fatherId"));
					list.add(fathreId);
				}
				Predicate[] p = new Predicate[list.size()];
				return criteriaBuilder.and(list.toArray(p));
			}
		};
		Page<MasterCode> sourceCodes = masterCodeJPA.findAll(specification, pageable);
		return sourceCodes;
	}

	/**
	 * @Description: 查找子字典信息
	 * @author WenBin
	 * @param code
	 * @return
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public List<MasterCode> findMasterCodeByFCode(Integer code) {

		List<MasterCode> list = null ;// redisCacheService.getCacheList(String.valueOf(code));
		if (list == null || list.size() == 0) {
			list = masterCodeJPA.findMasterCodeByFCode(code);
			//redisCacheService.setCacheList(String.valueOf(code), list);
		}
		return list;
	}

	@Override
	public List<MasterCode> findActiveMasterCodeByFCode(Integer code) {

		return masterCodeJPA.findActiveMasterCodeByFCode(code);
	}

	/**
	 * @Description: 所有激活的 MasterCodeDto 对象
	 * @author WenBin
	 * @param type
	 * @return
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public List<MasterCodeDto> findActiveMasterCodeDto(MasterCodeType type) {

		return castMasterCodeDto(masterCodeService.findActiveMasterCodeByFCode(type.getCode()));
	}

	/**
	 * @Description: 获取描述
	 * @author WenBin
	 * @param type
	 * @param key
	 * @return
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public String getMasterCodeDesc(MasterCodeType type, String key) {

		String value = "[未定义]";
		for (MasterCode mc : masterCodeService.findMasterCodeByFCode(type.getCode())) {
			if (mc.getDicKey() != null && mc.getDicKey().equals(key)) {
				return mc.getDicDesc();
			}
		}
		return value;
	}

	/**
	 * @Description: 查找对大数值 +1 返回
	 * @author WenBin
	 * @return
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public Integer findMaxCode() {

		return masterCodeJPA.findMaxCode();
	}

	/**
	 * @Description: 所有MasterCodeDto 对象
	 * @author WenBin
	 * @param type
	 *            枚举类型
	 * @return
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public List<MasterCodeDto> findAllMasterCodeDto(MasterCodeType type) {

		return castMasterCodeDto(masterCodeService.findMasterCodeByFCode(type.getCode()));
	}

	/**
	 * @Method: com.bozhon.service.base.impl.MasterCodeServiceImpl.castMasterCodeDto
	 * @Description: 转化 master code
	 * @author: WenBin
	 * @date: 2017年11月9日
	 * @version: 1.0
	 * @param list
	 *            MasterCode的集合对象
	 * @return
	 * 		List<MasterCodeDto>
	 * @update [日期YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	private List<MasterCodeDto> castMasterCodeDto(List<MasterCode> list) {

		MasterCodeDto dto = null;
		List<MasterCodeDto> dtoList = new ArrayList<>();
		for (MasterCode mc : list) {
			dto = new MasterCodeDto();
			dto.setKey(mc.getDicKey());
			dto.setValue(mc.getDicDesc());
			dto.setCode(mc.getDicCode());
			dto.setStatus(mc.getStatus());
			dto.setRemark(mc.getRemark());
			dtoList.add(dto);
		}
		return dtoList;
	}

	@Override
	public EasyuiPage<MasterCodeDto> querySunMasterCodeDto(EasyuiQuery bzpage, MasterCodeType type) throws Exception {
		Page<MasterCode> page = masterCodeService.querySunMasterCodes(bzpage, type);
		return new EasyuiPage<MasterCodeDto>(castMasterCodeDto(page.getContent()),page.getTotalElements(), page.getNumber()+1);
	}

	@Override
	public Page<MasterCode> querySunMasterCodes(EasyuiQuery bzPage, MasterCodeType type) throws Exception {
		final MasterCode mc = masterCodeService.findOneByCode(type.getCode());
		PageRequest pageable = new PageRequest(bzPage.getPageNo(), bzPage.getPageSize(), EasyuiUtil.getJpaSort(bzPage));
		Specification<MasterCode> specification = new Specification<MasterCode>() {
			@Override
			public Predicate toPredicate(Root<MasterCode> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> list = new ArrayList<Predicate>();
				// 未被删除的信息
				Predicate deleted = criteriaBuilder.equal(root.get("deleted"), AppConsts.DELETED_EXIST);
				list.add(deleted);
				// 系统级别
				Predicate level = criteriaBuilder.equal(root.get("dicLevel"), 1);
				list.add(level);
				// 父ID 查询
				Predicate fathreId = criteriaBuilder.equal(root.get("fatherId"), mc.getId());
				list.add(fathreId);
				Predicate[] p = new Predicate[list.size()];
				return criteriaBuilder.and(list.toArray(p));
			}
		};
		Page<MasterCode> sourceCodes = masterCodeJPA.findAll(specification, pageable);
		return sourceCodes;
	}

	@Override
	public EasyuiPage<MasterCodeDto> querySunMasterCodeDto(SearchComgrid bzpage, MasterCodeType type) throws Exception {
		Page<MasterCode> page = masterCodeService.querySunMasterCode(bzpage, type);
		return new EasyuiPage<MasterCodeDto>(castMasterCodeDto(page.getContent()),page.getTotalElements(), page.getNumber()+1);
	}

	@Override
	public Page<MasterCode> querySunMasterCode(final SearchComgrid bzpage, MasterCodeType type) throws Exception {
		final MasterCode mc = masterCodeService.findOneByCode(type.getCode());
		PageRequest pageable = new PageRequest(bzpage.getPageNo(), bzpage.getPageSize(), EasyuiUtil.getJpaSort(bzpage));
		Specification<MasterCode> specification = new Specification<MasterCode>() {
			@Override
			public Predicate toPredicate(Root<MasterCode> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> list = new ArrayList<Predicate>();
				// 未被删除的信息
				Predicate deleted = criteriaBuilder.equal(root.get("deleted"), AppConsts.DELETED_EXIST);
				list.add(deleted);
				// 系统级别
				Predicate level = criteriaBuilder.equal(root.get("dicLevel"), 1);
				list.add(level);
				// 父ID 查询
				Predicate fathreId = criteriaBuilder.equal(root.get("fatherId"), mc.getId());
				if(!StringUtil.isEmpty(bzpage.getQ())){
					Predicate dicDesc = criteriaBuilder.like(root.get("dicDesc").as(String.class),"%"+bzpage.getQ() == null? "" :bzpage.getQ()+"%");
					Predicate dicKey = criteriaBuilder.like(root.get("dicKey").as(String.class),"%"+bzpage.getQ() == null? "" :bzpage.getQ()+"%");
					list.add(criteriaBuilder.or(dicDesc,dicKey));
				}
				list.add(fathreId);
				Predicate[] p = new Predicate[list.size()];
				return criteriaBuilder.and(list.toArray(p));
			}
		};
		Page<MasterCode> sourceCodes = masterCodeJPA.findAll(specification, pageable);
		return sourceCodes;
	}
}
